﻿using APPFrameworkStudy.Common;
using APPFrameworkStudy.Domain.Mapping;
using APPFrameworkStudy.Repository;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace APPFrameworkStudy.DAL.Oracle
{
    public class BaseDbContext<T> : DbContext, IDataMapper<T> where T : class,IEntity, new()
    {

        public BaseDbContext()
            : base("name=OracleConnectionStringHome")
        {
            EFConfig config = new EFConfig();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.HasDefaultSchema("MYUSER");
            Utility.LoadMapping(modelBuilder);
            base.OnModelCreating(modelBuilder);
        }

        public DbSet<T> Entitys { get; set; }

        public virtual bool Create(T item)
        {
            this.Entitys.Add(item);
            return this.SaveChanges() > 0;
        }

        public virtual bool Update(T item)
        {
            this.Entry(item).State = EntityState.Modified;
            //当此记录数据库不存在时，将抛出异常
            return this.SaveChanges() > 0;
        }

        public virtual bool Delete(T item)
        {
            this.Entry(item).State = EntityState.Deleted;
            //当此记录数据库不存在时，将抛出异常
            return this.SaveChanges() > 0;
        }

        public IQueryable<T> GetQueryable()
        {
            return Entitys.AsNoTracking();
        }

        public virtual IList<T> GetAll()
        {
            return Entitys.ToList();
        }

        public IList<T> GetAll(IQueryable<T> query)
        {
            return query.ToList();
        }

        public IList<T> GetPage(int pageIndex, int pageSize, out int total)
        {
            total = GetCount();
            //默认ID排序
            return this.Entitys.OrderBy(t => t.ID)
               .Skip((pageIndex - 1) * pageSize)
               .Take(pageSize).ToList();
        }

        public IList<T> GetPage(IQueryable<T> query, int pageIndex, int pageSize, out int total)
        {
            total = GetCount();
            return query
               .Skip((pageIndex - 1) * pageSize)
               .Take(pageSize).ToList();
        }

        public virtual int GetCount()
        {
            return Entitys.AsNoTracking().Count();
        }

        public virtual int GetCountByCriteria(System.Linq.Expressions.Expression<Func<T, bool>> where)
        {
            return Entitys.AsNoTracking().Where(where).Count();
        }

        public virtual T GetByKey(object key)
        {
            return Entitys.Find(key);
        }

        public virtual IList<T> GetByCriteria(System.Linq.Expressions.Expression<Func<T, bool>> where)
        {
            return Entitys.AsNoTracking().Where(where).ToList();
        }

        public IList<T> GetPageByCriteria(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> where)
        {
            total = this.Entitys.AsNoTracking().Where(where).Count();
            return this.Entitys.AsNoTracking().Where(where).OrderBy(t => t.ID)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize).ToList();
        }

        public IList<T> GetPageByCriteria(IQueryable<T> query, int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> where)
        {
            total = query.Where(where).Count();
            return query.Where(where)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize).ToList();
        }

        public IList<T> GetByCriteria(IQueryable<T> query, Expression<Func<T, bool>> where)
        {
            return query.Where(where).ToList();
        }
    }
}
